package com.tju.resource.business.sys;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.tju.resource.annotation.Log;
import com.tju.resource.tool.bcrypt.BCryptPasswordEncoderUtil;
import com.tju.resource.result.Result;
import com.tju.resource.result.ResultEnum;
import com.tju.resource.result.ResultUtil;
import com.tju.resource.tool.enum_utils.FunctionType;
import com.tju.resource.tool.tool.ChineseExceptionUtils;
import com.tju.resource.tool.tool.EmptyUtils;
import com.tju.resource.common.ServiceException;
import com.tju.resource.mapper.SysUserMapper;
import com.tju.resource.mapper.SysUserRoleMapper;
import com.tju.resource.model.SysUser;
import com.tju.resource.model.SysUserRole;
import com.tju.resource.tool.tool.ClientParameters;
import com.tju.resource.tool.tool.QuickQuery;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Optional;

/**
 * 用户实现类
 */
@Slf4j
@Service
public class SysUserServiceImpl implements SysUserService {

    @Autowired
    private SysUserMapper sysUserMapper;
    @Autowired
    private SysUserRoleMapper sysUserRoleMapper;
    @Autowired
    private ChineseExceptionUtils zh_CH;
    @Autowired
    private BCryptPasswordEncoderUtil bCryptPasswordEncoderUtil;

    /**
     * 新增用户信息
     *
     * @param sysUser
     * @return
     */
    @Override
    @Transactional
    @Log(type = FunctionType.Add)
    public Result<Object> addUserInformation(SysUser sysUser) {
        try {
            QueryWrapper<SysUser> wrapper = new QueryWrapper<>();
            wrapper.eq("username", sysUser.getUsername());
            if (EmptyUtils.isEmpty(sysUserMapper.selectOne(wrapper))) {
                if (sysUser.getOnePassword().equals(sysUser.getPassword())) {
                    sysUser.setPassword(BCryptPasswordEncoderUtil.encrypt(sysUser.getPassword()));
                    if (sysUserMapper.insert(sysUser) > 0) {
                        for (Long lo : sysUser.getRoleId()) {
                            sysUserRoleMapper.insert(new SysUserRole(sysUser.getId(), lo));
                        }
                        return ResultUtil.success(ResultEnum.SUCCESS, zh_CH.AddedSuccessfully);
                    }
                } else {
                    return ResultUtil.error(ResultEnum.UNKONW_ERROR, zh_CH.PasswordInputIsInconsistent);
                }
            } else {
                return ResultUtil.error(ResultEnum.UNKONW_ERROR, zh_CH.UsernameOccupied);
            }

        } catch (Exception e) {
            throw new ServiceException(zh_CH.AddFailed);
        }
        return ResultUtil.error(ResultEnum.UNKONW_ERROR, zh_CH.AddFailed);
    }

    /**
     * 删除用户信息
     *
     * @param sysUser
     * @return
     */
    @Override
    @Transactional
    @Log(type = FunctionType.Delete)
    public Result<Object> deleteUserInformation(SysUser sysUser) {
        try {
            return Optional.ofNullable(sysUser.getId())
                    .map(i -> sysUserMapper.deleteById(sysUser.getId()))
                    .map(s -> {
                        QueryWrapper<SysUserRole> wrapper = new QueryWrapper<>();
                        wrapper.eq("user_id", sysUser.getId());
                        return sysUserRoleMapper.delete(wrapper);
                    })
                    .filter(integer -> integer > 0)
                    .map(s -> ResultUtil.success(ResultEnum.SUCCESS, zh_CH.SuccessfullyDeleted))
                    .orElseThrow(() -> new ServiceException(zh_CH.FailedToDelete));
        } catch (Exception e) {
            throw new ServiceException(zh_CH.FailedToDelete);
        }
    }

    /**
     * 修改用户信息
     *
     * @param sysUser
     * @return
     */
    @Override
    @Transactional
    @Log(type = FunctionType.Modify)
    public Result<Object> modifyUserInformation(SysUser sysUser) {
        try {
            if (sysUserMapper.modifyUserInformation(sysUser) > 0) {
                QueryWrapper<SysUserRole> wrapper = new QueryWrapper<>();
                wrapper.eq("user_id", sysUser.getId());
                sysUserRoleMapper.delete(wrapper);
                for (Long lo : sysUser.getRoleId()) {
                    sysUserRoleMapper.insert(new SysUserRole(sysUser.getId(), lo));
                }
                return ResultUtil.success(ResultEnum.SUCCESS, zh_CH.SuccessfullyModified);
            }
        } catch (Exception e) {
            throw new ServiceException(zh_CH.FailToEdit);
        }
        return ResultUtil.error(ResultEnum.UNKONW_ERROR, zh_CH.FailToEdit);
    }

    /**
     * 修改用户密码
     *
     * @param sysUser
     * @return
     */
    @Transactional
    @Override
    @Log(type = FunctionType.Modify)
    public Result<Object> modifyUserPassword(SysUser sysUser) {
        try {
            if (EmptyUtils.isNotEmpty(sysUser.getUsername()) && EmptyUtils.isNotEmpty(sysUser.getOnePassword()) && EmptyUtils.isNotEmpty(sysUser.getOldPassword()) && EmptyUtils.isNotEmpty(sysUser.getPassword())) {
                QueryWrapper<SysUser> wrapper = new QueryWrapper<>();
                wrapper.eq("username", sysUser.getUsername());
                SysUser user = sysUserMapper.selectOne(wrapper);
                if (bCryptPasswordEncoderUtil.matches(sysUser.getOldPassword(), user.getPassword())) {
                    if (sysUser.getOnePassword().equals(sysUser.getPassword())) {
                        sysUser.setPassword(BCryptPasswordEncoderUtil.encrypt(sysUser.getPassword()));
                        wrapper.clear();
                        wrapper.eq("username", sysUser.getUsername());
                        if (sysUserMapper.update(sysUser, wrapper) > 0)
                            return ResultUtil.success(ResultEnum.SUCCESS, zh_CH.SuccessfullyModified);
                    } else
                        return ResultUtil.error(ResultEnum.UNKONW_ERROR, zh_CH.PasswordInputIsInconsistent);
                } else
                    return ResultUtil.error(ResultEnum.UNKONW_ERROR, zh_CH.OldPassword);
            } else {
                return ResultUtil.error(ResultEnum.UNKONW_ERROR, zh_CH.NonEmpty);
            }
        } catch (Exception e) {
            throw new ServiceException(zh_CH.FailToEdit);
        }
        return ResultUtil.error(ResultEnum.UNKONW_ERROR, zh_CH.FailToEdit);
    }

    /**
     * 查询全部用户信息
     *
     * @param parameter
     * @return
     */
    @Override
    @Log(type = FunctionType.List)
    public Result<Object> getPageUser(ClientParameters parameter) {
        try {
            Page<SysUser> page = new Page<>(parameter.getPage(), parameter.getLimit());
            IPage<SysUser> iPage = sysUserMapper.getPageUser(page, parameter);
            return ResultUtil.success(ResultEnum.SUCCESS, iPage.getRecords(), iPage.getTotal());
        } catch (Exception e) {
            e.printStackTrace();
        }
        return ResultUtil.error(ResultEnum.UNKONW_ERROR);
    }

    /**
     * 查询个人用户信息
     *
     * @param sysUser
     * @return
     */
    @Override
    public Result<Object> getPersonalInformation(SysUser sysUser) {
        try {
            SysUser user = sysUserMapper.getPersonalInformation(sysUser);
            if (EmptyUtils.isNotEmpty(user))
                return ResultUtil.success(ResultEnum.SUCCESS, user);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return ResultUtil.error(ResultEnum.UNKONW_ERROR);
    }

    @Override
    public SysUser byName(String userName) {
        return QuickQuery.byOne(sysUserMapper, "username", userName);
    }
}
